<!DOCTYPE html>
<!-- saved from url=(0062)https://www.tboxn.com/wp-content/themes/onenav/fx/io-fx02.html -->
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	
	<meta name="robots" content="noindex">
	<title>io-fx02</title>
	<meta name="author" content="iowen.cn">
	<style>
		body {background: #1B1D1F;overflow: hidden;}
		canvas {display: block;}
	</style>
</head>
<body>
	<canvas id="canvas" width="1912" height="924"></canvas>
	<script>
		var canvas,ctx,width,height,size,lines,tick;
		function line() {
			this.path = [];
			this.speed = rand(10, 20);
			this.count = randInt(10, 30);
			this.x = width / 2, +1;
			this.y = height / 2 + 1;
			this.target = {
				x: width / 2,
				y: height / 2
			};
			this.dist = 0;
			this.angle = 0;
			this.hue = tick / 5;
			this.life = 1;
			this.updateAngle();
			this.updateDist();
		}
		line.prototype.step = function(i) {
			this.x += Math.cos(this.angle) * this.speed;
			this.y += Math.sin(this.angle) * this.speed;
		
			this.updateDist();
		
			if (this.dist < this.speed) {
				this.x = this.target.x;
				this.y = this.target.y;
				this.changeTarget();
			}
			this.path.push({
				x: this.x,
				y: this.y
			});
			if (this.path.length > this.count) {
				this.path.shift();
			}
		
			this.life -= 0.001;
		
			if (this.life <= 0) {
				this.path = null;
				lines.splice(i, 1);
			}
		};

		line.prototype.updateDist = function() {
			var dx = this.target.x - this.x,
				dy = this.target.y - this.y;
			this.dist = Math.sqrt(dx * dx + dy * dy);
		}
		line.prototype.updateAngle = function() {
			var dx = this.target.x - this.x,
				dy = this.target.y - this.y;
			this.angle = Math.atan2(dy, dx);
		}
		line.prototype.changeTarget = function() {
			var randStart = randInt(0, 3);
			switch (randStart) {
				case 0: // up
					this.target.y = this.y - size;
					break;
				case 1: // right
					this.target.x = this.x + size;
					break;
				case 2: // down
					this.target.y = this.y + size;
					break;
				case 3: // left
					this.target.x = this.x - size;
			}
			this.updateAngle();
		};
		line.prototype.draw = function(i) {
			ctx.beginPath();
			var rando = rand(0, 10);
			for (var j = 0, length = this.path.length; j < length; j++) {
				ctx[(j === 0) ? 'moveTo' : 'lineTo'](this.path[j].x + rand(-rando, rando), this.path[j].y + rand(-rando, rando));
			}
			ctx.strokeStyle = 'hsla(' + rand(this.hue, this.hue + 30) + ', 80%, 55%, ' + (this.life / 3) + ')';
			ctx.lineWidth = rand(0.1, 2);
			ctx.stroke();
		};
		function rand(min, max) {
			return Math.random() * (max - min) + min;
		}
		function randInt(min, max) {
			return Math.floor(min + Math.random() * (max - min + 1));
		};
		function init() {
			canvas = document.getElementById('canvas');
			ctx = canvas.getContext('2d');
			size = 30;
			lines = [];
			reset();
			loop();
		}
		function reset() {
			width = Math.ceil(window.innerWidth / 2) * 2;
			height = Math.ceil(window.innerHeight / 2) * 2;
			tick = 0;
		
			lines.length = 0;
			canvas.width = width;
			canvas.height = height;
		}
		function create() {
			if (tick % 10 === 0) {
				lines.push(new line());
			}
		}
		function step() {
			var i = lines.length;
			while (i--) {
				lines[i].step(i);
			}
		}
		function clear() {
			ctx.globalCompositeOperation = 'destination-out';
			ctx.fillStyle = 'hsla(0, 0%, 0%, 0.1';
			ctx.fillRect(0, 0, width, height);
			ctx.globalCompositeOperation = 'lighter';
		}
		function draw() {
			ctx.save();
			ctx.translate(width / 2, height / 2);
			ctx.rotate(tick * 0.001);
			var scale = 0.8 + Math.cos(tick * 0.02) * 0.2;
			ctx.scale(scale, scale);
			ctx.translate(-width / 2, -height / 2);
			var i = lines.length;
			while (i--) {
				lines[i].draw(i);
			}
			ctx.restore();
		}
		function loop() {
			requestAnimationFrame(loop);
			create();
			step();
			clear();
			draw();
			tick++;
		}
		function onresize() {
			reset();
		}
		window.addEventListener('resize', onresize);
		init();
	</script>

</body></html>